package com.xiaojie.lock;

import com.xiaojie.utils.RedisPoolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.util.UUID;

/**
 * @author xiaojie
 * @version 1.0
 * @description: 基于redis实现分布式锁
 * @date 2021/9/19 21:17
 */
@Component
public class RedisDistributeLock {
    @Autowired
    private RedisPoolUtil redisPoolUtil;

    /**
     * @description:
     * @param: key 键值
     * @param: notLockTimeOut 为获取锁的等待时间
     * @param: timeOut 键值过期时间
     * @return: java.lang.String
     * @author xiaojie
     * @date: 2021/9/19 21:15
     */
    public String getLock(String key, Integer notLockTimeOut, Long timeOut) {
        Jedis jedis = redisPoolUtil.getJedis();
        //计算锁的超时时间
        Long endTime = System.currentTimeMillis() + notLockTimeOut;
        //当前时间比锁的超时时间小，证明获取锁时间没有超时，继续获取
        while (System.currentTimeMillis() < endTime) {
            String lockValue = UUID.randomUUID().toString();
            //如果设置成功返回1 获取到锁，如果返回0 获取锁失败，继续获取
            if (1 == jedis.setnx(key, lockValue)) {
                //设置键值过期时间,防止死锁
                jedis.expire(key, timeOut);
                return lockValue;
            }
        }
        //关闭连接
        try {
            if (jedis != null) {
                jedis.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @description: 释放锁
     * @param: key
     * @return: boolean
     * @author xiaojie
     * @date: 2021/9/19 21:25
     */
    public boolean unLock(String key, String lockValue) {
        //获取Redis连接
        Jedis jedis =null;
        try {
            jedis = redisPoolUtil.getJedis();
            // 判断获取锁的时候保证自己删除自己
            if (lockValue.equals(jedis.get(key))) {
                return jedis.del(key) > 0 ? true : false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        return false;
    }
}
